package org.i9.slb.platform.anseko.console.controller;

import org.i9.slb.platform.anseko.common.PowerState;
import org.i9.slb.platform.anseko.console.service.SimulatorService;
import org.i9.slb.platform.anseko.console.utils.HttpResponse;
import org.i9.slb.platform.anseko.console.utils.Result;
import org.i9.slb.platform.anseko.provider.IDubboInstanceRemoteService;
import org.i9.slb.platform.anseko.provider.IDubboSimulatorRemoteService;
import org.i9.slb.platform.anseko.provider.dto.InstanceDto;
import org.i9.slb.platform.anseko.provider.dto.SimulatorDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;

/**
 * 模拟器控制器
 *
 * @author R12
 * @date 2018.08.30
 */
@Controller
public class SimulatorController {

    @Autowired
    private IDubboSimulatorRemoteService dubboSimulatorRemoteService;

    @Autowired
    private IDubboInstanceRemoteService dubboInstanceRemoteService;

    @Autowired
    private SimulatorService simulatorService;

    /**
     * 模拟器列表
     *
     * @return
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(Model model) {
        HashMap<String, InstanceDto> result = new HashMap<String, InstanceDto>();
        List<InstanceDto> instanceDtos = this.dubboInstanceRemoteService.getInstanceDtoList();
        for (InstanceDto instanceDto : instanceDtos) {
            result.put(instanceDto.getId(), instanceDto);
        }
        List<SimulatorDto> simulatorDtos = this.dubboSimulatorRemoteService.getSimulatorDtoList();
        for (SimulatorDto simulatorDto : simulatorDtos) {
            InstanceDto instanceDto = result.get(simulatorDto.getInstance());
            simulatorDto.setInstanceDto(instanceDto);
        }
        model.addAttribute("simulatorDtos", simulatorDtos);
        model.addAttribute("instanceDtos", instanceDtos);
        return "index";
    }

    /**
     * vncviewer
     *
     * @param simulatorId
     * @param model
     * @return
     */
    @RequestMapping(value = "/vncviewer/{simulatorId}", method = RequestMethod.GET)
    public String vncviewer(@PathVariable("simulatorId") String simulatorId, Model model) {
        SimulatorDto simulatorDto = dubboSimulatorRemoteService.getSimulatorDtoInfo(simulatorId);
        model.addAttribute("simulatorDto", simulatorDto);
        return "vncviewer";
    }

    /**
     * 启动模拟器
     *
     * @param simulatorId
     * @throws Exception
     */
    @RequestMapping(value = "/start/{simulatorId}", method = RequestMethod.POST)
    @ResponseBody
    public Result start(@PathVariable("simulatorId") String simulatorId) {
        SimulatorDto simulatorDto = this.dubboSimulatorRemoteService.getSimulatorDtoInfo(simulatorId);
        this.dubboSimulatorRemoteService.refreshSimulatorPowerState(simulatorDto.getId(), PowerState.RUNING.ordinal());
        try {
            this.simulatorService.startSimulator(simulatorDto);
            return HttpResponse.ok();
        } catch (Exception e) {
            return HttpResponse.error(e);
        }
    }

    /**
     * 启动模拟器
     *
     * @throws Exception
     */
    @RequestMapping(value = "/batch_start", method = RequestMethod.POST)
    @ResponseBody
    public Result start() {
        for (SimulatorDto simulatorDto : this.dubboSimulatorRemoteService.getSimulatorDtoList()) {
            this.dubboSimulatorRemoteService.refreshSimulatorPowerState(simulatorDto.getId(), PowerState.RUNING.ordinal());
            try {
                this.simulatorService.startSimulator(simulatorDto);
            } catch (Exception e) {
                return HttpResponse.error(e);
            }
        }
        return HttpResponse.ok();
    }

    /**
     * 重启模拟器
     *
     * @param simulatorId
     * @throws Exception
     */
    @RequestMapping(value = "/reboot/{simulatorId}", method = RequestMethod.POST)
    @ResponseBody
    public Result reboot(@PathVariable("simulatorId") String simulatorId) {
        SimulatorDto simulatorDto = this.dubboSimulatorRemoteService.getSimulatorDtoInfo(simulatorId);
        this.dubboSimulatorRemoteService.refreshSimulatorPowerState(simulatorDto.getId(), PowerState.RUNING.ordinal());
        try {
            this.simulatorService.rebootSimulator(simulatorDto);
            return HttpResponse.ok();
        } catch (Exception e) {
            return HttpResponse.error(e);
        }
    }

    /**
     * 重启模拟器
     *
     * @throws Exception
     */
    @RequestMapping(value = "/batch_reboot", method = RequestMethod.POST)
    @ResponseBody
    public Result reboot() {
        for (SimulatorDto simulatorDto : this.dubboSimulatorRemoteService.getSimulatorDtoList()) {
            this.dubboSimulatorRemoteService.refreshSimulatorPowerState(simulatorDto.getId(), PowerState.RUNING.ordinal());
            try {
                this.simulatorService.rebootSimulator(simulatorDto);
            } catch (Exception e) {
                return HttpResponse.error(e);
            }
        }
        return HttpResponse.ok();
    }

    /**
     * 关闭模拟器
     *
     * @param simulatorId
     * @throws Exception
     */
    @RequestMapping(value = "/shutdown/{simulatorId}", method = RequestMethod.POST)
    @ResponseBody
    public Result shutdown(@PathVariable("simulatorId") String simulatorId) {
        SimulatorDto simulatorDto = this.dubboSimulatorRemoteService.getSimulatorDtoInfo(simulatorId);
        this.dubboSimulatorRemoteService.refreshSimulatorPowerState(simulatorDto.getId(), PowerState.CLOSE.ordinal());
        try {
            this.simulatorService.shutdownSimulator(simulatorDto);
            return HttpResponse.ok();
        } catch (Exception e) {
            return HttpResponse.error(e);
        }
    }

    /**
     * 关闭模拟器
     *
     * @throws Exception
     */
    @RequestMapping(value = "/batch_shutdown", method = RequestMethod.POST)
    @ResponseBody
    public Result shutdown() {
        for (SimulatorDto simulatorDto : dubboSimulatorRemoteService.getSimulatorDtoList()) {
            this.dubboSimulatorRemoteService.refreshSimulatorPowerState(simulatorDto.getId(), PowerState.CLOSE.ordinal());
            try {
                this.simulatorService.shutdownSimulator(simulatorDto);
            } catch (Exception e) {
                return HttpResponse.error(e);
            }
        }
        return HttpResponse.ok();
    }

    /**
     * 销毁模拟器
     *
     * @param simulatorId
     * @throws Exception
     */
    @RequestMapping(value = "/destroy/{simulatorId}", method = RequestMethod.POST)
    @ResponseBody
    public Result destroy(@PathVariable("simulatorId") String simulatorId) {
        SimulatorDto simulatorDto = this.dubboSimulatorRemoteService.getSimulatorDtoInfo(simulatorId);
        this.dubboSimulatorRemoteService.removeSimulatorInfo(simulatorId);
        try {
            this.simulatorService.destroySimulator(simulatorDto);
            return HttpResponse.ok();
        } catch (Exception e) {
            return HttpResponse.error(e);
        }
    }

    /**
     * 创建模拟器
     *
     * @param httpServletRequest
     * @throws Exception
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    public Result create(HttpServletRequest httpServletRequest) {
        String simulatorName = httpServletRequest.getParameter("simulatorName");
        String instance = httpServletRequest.getParameter("instance");
        try {
            SimulatorDto simulatorDto = this.dubboSimulatorRemoteService.createSimulatorInfo(simulatorName, instance);
            this.simulatorService.createSimulator(simulatorDto);
            return HttpResponse.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return HttpResponse.error(e);
        }
    }
}
